package com.interview.salesorder.repository;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.TypedQuery;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;

import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.transform.Transformers;
import org.springframework.stereotype.Repository;

import com.interview.core.page.Page;
import com.interview.orderdetail.entity.OrderDetail;
import com.interview.salesorder.entity.SalesOrder;
import com.interview.salesorder.entity.SalesOrder_;
import com.interview.salesorder.query.SalesOrderConditionQuery;

@Repository
public class SalesorderRepository {

	@PersistenceContext
	private EntityManager entityManager;

	public SalesOrder findOneSalesOrder(String id) {
		return entityManager.find(SalesOrder.class, id);
	}

	public SalesOrder updateSalesOrder(SalesOrder order) {

		String id = order.getId();
		SalesOrder salesOrderBefor = findOneSalesOrder(id);
		List<OrderDetail> orderLists = order.getOrderList();

		if (orderLists == null || orderLists.size() == 0) {

			salesOrderBefor.setCustomerId(order.getCustomerId());
			salesOrderBefor.setCustomerName(order.getCustomerName());
			salesOrderBefor.setEmployeeInfoId(order.getEmployeeInfoId());
			salesOrderBefor.setEmployeeInfoName(order.getEmployeeInfoName());
			salesOrderBefor.setOrderCode(order.getOrderCode());
			salesOrderBefor.setOrderCreateTime(order.getOrderCreateTime());
			salesOrderBefor.setSumCost(order.getSumCost());
			salesOrderBefor.getOrderList().clear();

			return entityManager.merge(salesOrderBefor);
		} else {

			return entityManager.merge(order);
		}

	}

	public SalesOrder saveSalesOrder(SalesOrder order) {
		entityManager.persist(order);
		return order;
	}

	public void deleteSalesOrder(String id) {

		entityManager.remove(findOneSalesOrder(id));
	}

	public List<SalesOrder> findAllSalesOrder() {
		CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
		CriteriaQuery<SalesOrder> criteriaQuery = criteriaBuilder
				.createQuery(SalesOrder.class);
		Root<SalesOrder> root = criteriaQuery.from(SalesOrder.class);

		List<SalesOrder> salesOrder = entityManager.createQuery(criteriaQuery)
				.getResultList();

		return salesOrder;
	}

	public Page findSalesOrderBySalesOrderConditionQuery(
			SalesOrderConditionQuery conditionQuery) {

		Integer pageIndex = conditionQuery.getPageIndex();
		Integer pageSize = conditionQuery.getPageSize();

		String employeeInfoName = conditionQuery.getEmployeeInfoName();
		String customerName = conditionQuery.getCustomerName();

		String orderCode = conditionQuery.getOrderCode();

		Date dateBegin = conditionQuery.getOrderCreateTimeBegin();
		Date dateEnd = conditionQuery.getOrderCreateTimeEnd();

		Double sumCostBegin = conditionQuery.getSumCostBegin();
		Double sumCostEnd = conditionQuery.getSumCostEnd();
		if (sumCostBegin == 0.0 || sumCostBegin < 0.0) {
			sumCostBegin = null;
		}
		if (sumCostEnd == 0.0 || sumCostEnd < 0.0) {
			sumCostEnd = null;
		}

		List<Predicate> predicates = new ArrayList<Predicate>();

		CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
		CriteriaQuery<SalesOrder> criteriaQuery = criteriaBuilder
				.createQuery(SalesOrder.class);
		Root<SalesOrder> root = criteriaQuery.from(SalesOrder.class);

		if (employeeInfoName != null) {
			Predicate predicateEmployeeInfoName = criteriaBuilder.like(
					root.get(SalesOrder_.employeeInfoName), "%"
							+ employeeInfoName + "%");
			predicates.add(predicateEmployeeInfoName);
		}

		if (customerName != null) {
			Predicate predicateCustomerName = criteriaBuilder.like(
					root.get(SalesOrder_.customerName), "%" + customerName
							+ "%");

			predicates.add(predicateCustomerName);
		}

		if (orderCode != null) {

			Predicate predicateOrderCode = criteriaBuilder.like(
					root.get(SalesOrder_.orderCode), "%" + orderCode + "%");

			predicates.add(predicateOrderCode);
		}

		if (dateBegin != null) {
			Predicate predicateDateBegin = criteriaBuilder
					.greaterThanOrEqualTo(
							root.get(SalesOrder_.orderCreateTime), dateBegin);

			predicates.add(predicateDateBegin);
		}

		if (dateEnd != null) {
			Predicate predicateDateEnd = criteriaBuilder.lessThanOrEqualTo(
					root.get(SalesOrder_.orderCreateTime), dateEnd);
			predicates.add(predicateDateEnd);
		}

		if (sumCostBegin != null) {
			Predicate predicateSumCostBegin = criteriaBuilder
					.greaterThanOrEqualTo(root.get(SalesOrder_.sumCost),
							sumCostBegin);

			predicates.add(predicateSumCostBegin);
		}

		if (sumCostEnd != null) {
			Predicate predicateSumCostEnd = criteriaBuilder.lessThanOrEqualTo(
					root.get(SalesOrder_.sumCost), sumCostEnd);
			predicates.add(predicateSumCostEnd);
		}

		criteriaQuery.where(criteriaBuilder.and(predicates
				.toArray(new Predicate[predicates.size()])));

		TypedQuery<SalesOrder> query = entityManager.createQuery(criteriaQuery);

		Integer total = query.getResultList().size();

		if (pageIndex < 0) {
			pageIndex = 0;
		}

		if (pageSize < 0) {
			pageSize = 0;
		}

		List<SalesOrder> saOrders = query.setFirstResult(pageIndex)
				.setMaxResults(pageSize).getResultList();

		Page page = new Page();
		page.setList(saOrders);
		page.setPageIndex(pageIndex);
		page.setPageSize(pageSize);
		page.setTotal(total);

		return page;
	}

}
